package edu.westga.vocalengineer.audio;

/**
 * AudioTools
 *  A collection of useful methods for dealing with audio data.
 * @author mfarmer2
 *
 */
public class AudioTools {
	/**
	 * getSample
	 *   Access a byte array as a short array, instead.  (Eases sound clip modification.)
	 *   The new short array bounds must be respected or an exception will be thrown.
	 * @param b A byte array to be accessed as a short array.
	 * @param pos The offset to the desired short.
	 * @return The desired short.
	 */
	public static short getSample(byte[] b, int pos) {
		return (short) (((b[pos + 1] & 0xFF) << 8) | 
				        (b[pos] & 0xFF));
	}

	/**
	 * setSample
	 *   Treats a pair of elements in a byte array as a short and modifies it.  Bounds
	 *   as a short array should be respected or an exception will be thrown.
	 * @param b The buffer to be accessed as a short array.
	 * @param pos The position (as a short array) to set to the new value.
	 * @param value The value to be set.
	 */
	public static void setSample(byte[] b, int pos, short value) {
		b[pos] = (byte) (value & 0xFF);
		b[pos + 1] = (byte) ((value >> 8) & 0xFF);
	}

	/**
	 * convertByteArrayToSamples
	 *   Takes a byte array and converts it to a standard short
	 *   array representing PCM samples.
	 * @param b The raw byte array.
	 * @return A short array of PCM data.
	 */
	public static short[] convertByteArrayToSamples(byte[] b) {
		short[] result = new short[b.length / 2];
		for(int i = 0; i < result.length; i++) {
			result[i] = AudioTools.getSample(b, i * 2);
		}
		return result;
	}
	
	/**
	 * convertSamplesToByteArray
	 *  Takes a PCM short array and converts it to a raw byte array.
	 * @param samples The array of PCM short data.
	 * @return A raw byte array.
	 */
	public static byte[] convertSamplesToByteArray(short[] samples) {
		byte[] result = new byte[samples.length * 2];
		for(int i = 0; i < samples.length; i++) {
			AudioTools.setSample(result, i*2, samples[i]);
		}
		return result;
	}
	
	// pure static class; we don't want a public constructor
	private AudioTools() { }
}
